home *** CD-ROM | disk | FTP | other *** search
- // FileZilla Server - a Windows ftp server
-
- // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
-
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
-
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
-
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- // Based upon example code from Nishant S
- // Original code is available under http://www.codeproject.com/system/serviceskeleton.asp
-
- #include "stdafx.h"
- #include "server.h"
- #include "Options.h"
-
- void ServiceMain(DWORD argc, LPTSTR *argv);
- void ServiceCtrlHandler(DWORD nControlCode);
- BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
- DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
- DWORD dwWaitHint);
- BOOL StartServiceThread();
- DWORD ServiceExecutionThread(LPDWORD param);
- HANDLE hServiceThread=0;
- void KillService();
-
- SERVICE_STATUS_HANDLE nServiceStatusHandle = 0;
- HANDLE killServiceEvent = 0;
- BOOL nServiceRunning = 0;
- DWORD nServiceCurrentStatus = 0;
-
- static TCHAR ServiceDisplayName[257] = _T("FileZilla Server FTP server");
- static TCHAR ServiceName[257] = _T("FileZilla Server");
-
- int SetAdminPort(int port);
- int ReloadConfig();
- int CompatMain(LPCSTR lpCmdLine);
-
- void LoadServiceName()
- {
- COptions *pOptions = new COptions();
-
- CStdString name = pOptions->GetOption(OPTION_SERVICE_NAME);
- if (name.size() > 0 && name.size() < 256)
- _tcscpy(ServiceName, name);
-
- CStdString display_name = pOptions->GetOption(OPTION_SERVICE_DISPLAY_NAME);
- if (display_name.size() > 0 && display_name.size() < 256)
- _tcscpy(ServiceDisplayName, display_name);
-
- delete pOptions;
-
- }
-
- int SetServiceName(LPCTSTR serviceName)
- {
- size_t len = _tcslen(serviceName);
- if (!len || len > 256)
- return 1;
-
- COptions *pOptions = new COptions();
- pOptions->SetOption(OPTION_SERVICE_NAME, serviceName);
- delete pOptions;
-
- pOptions = new COptions();
- if (pOptions->GetOption(OPTION_SERVICE_NAME) != serviceName)
- {
- delete pOptions;
- return 1;
- }
- delete pOptions;
-
- return 0;
- }
-
- int SetServiceDisplayName(LPCTSTR serviceDisplayName)
- {
- size_t len = _tcslen(serviceDisplayName);
- if (!len || len > 256)
- return 1;
-
- COptions *pOptions = new COptions();
- pOptions->SetOption(OPTION_SERVICE_DISPLAY_NAME, serviceDisplayName);
- delete pOptions;
-
- pOptions = new COptions();
- if (pOptions->GetOption(OPTION_SERVICE_DISPLAY_NAME) != serviceDisplayName)
- {
- delete pOptions;
- return 1;
- }
- delete pOptions;
-
- return 0;
- }
-
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow )
- {
- BOOL bNT = FALSE;
- BOOL bInstalled = FALSE;
- BOOL dwCurrentState = 0;
-
- int nAction = 0;
- if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
- {
- lpCmdLine++;
- if (strlen(lpCmdLine) >= 6 && !strncmp(lpCmdLine, "compat", 6))
- {
- lpCmdLine += 6;
- while (lpCmdLine[0] == ' ')
- lpCmdLine++;
- return CompatMain(lpCmdLine);
- }
- else if (!strcmp(lpCmdLine, "install"))
- nAction = 1;
- else if (!strcmp(lpCmdLine, "uninstall"))
- nAction = 2;
- else if (!strcmp(lpCmdLine, "start"))
- nAction = 3;
- else if (!strcmp(lpCmdLine, "stop"))
- nAction = 4;
- else if (!strcmp(lpCmdLine, "install auto"))
- nAction = 5;
- else if (strlen(lpCmdLine) >= 10 && !strncmp(lpCmdLine, "adminport ", 10))
- nAction = 6;
- else if (!strcmp(lpCmdLine, "reload-config"))
- nAction = 7;
- else if (!strncmp(lpCmdLine, "servicename ", 12))
- return SetServiceName(CStdString(lpCmdLine + 12));
- else if (!strncmp(lpCmdLine, "servicedisplayname ", 19))
- return SetServiceDisplayName(CStdString(lpCmdLine + 19));
- }
-
- LoadServiceName();
-
- if (nAction == 6)
- return SetAdminPort(atoi(lpCmdLine + 10));
- else if (nAction == 7)
- return ReloadConfig();
-
- SC_HANDLE hService, hScm;
- hScm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
-
- if (hScm)
- {
- bNT = TRUE;
- hService = OpenService(hScm, ServiceName, GENERIC_READ);
- if (hService)
- {
- bInstalled = TRUE;
-
- SERVICE_STATUS ServiceStatus;
- if (QueryServiceStatus(hService, &ServiceStatus))
- {
- dwCurrentState = ServiceStatus.dwCurrentState;
- if (dwCurrentState == SERVICE_START_PENDING)
- {
- CloseServiceHandle(hService);
- CloseServiceHandle(hScm);
-
- const SERVICE_TABLE_ENTRY servicetable[]=
- {
- {ServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain},
- {NULL,NULL}
- };
- BOOL success;
- success=StartServiceCtrlDispatcher(servicetable);
- if (!success)
- {
- int nError=GetLastError();
- TCHAR buffer[1000];
- _stprintf(buffer, _T("StartServiceCtrlDispatcher failed with error %d"), nError);
- MessageBox(0, buffer, _T("Error while starting service"), MB_OK);
- //error occured
- }
- return 0;
- }
- }
-
- CloseServiceHandle(hService);
- }
- CloseServiceHandle(hScm);
- }
- else
- {
- if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
- {
- lpCmdLine--;
- return CompatMain(lpCmdLine);
- }
- }
-
- if (!bInstalled)
- {
- if (nAction==1 || nAction==5 || (nAction == 0 && MessageBox(0, _T("Install Service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES))
- {
- hScm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
- if(!hScm)
- {
- return 1;
- }
- int nStartMode = (nAction==5)?SERVICE_AUTO_START:SERVICE_DEMAND_START;
- if (!nAction)
- if (MessageBox(0, _T("Autostart service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)
- nStartMode = SERVICE_AUTO_START;
- TCHAR buffer[MAX_PATH + 3];
- buffer[0] = '"';
- DWORD written = GetModuleFileName(0, buffer + 1, MAX_PATH);
- if (!written)
- {
- CloseServiceHandle(hScm);
-
- MessageBox(0, _T("Failed to get own executable path"), _T("Could not install server"), MB_ICONSTOP);
- return 1;
- }
- buffer[written + 1] = '"';
- buffer[written + 2] = 0;
-
- hService=CreateService(hScm, ServiceName,
- ServiceDisplayName,
- SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, nStartMode,
- SERVICE_ERROR_NORMAL,
- buffer,
- 0, 0, 0, 0, 0);
- if(!hService)
- {
- CloseServiceHandle(hScm);
- return 1;
- }
- CloseServiceHandle(hService);
- CloseServiceHandle(hScm);
- dwCurrentState = SERVICE_STOPPED;
- }
- else
- return 0;
- }
-
- if (dwCurrentState == SERVICE_STOPPED && (nAction==3 || (nAction == 0 && MessageBox(0, _T("Start server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
- {
- SC_HANDLE hService,hScm;
- hScm=OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
- if(!hScm)
- {
- return 1;
- }
- hService=OpenService(hScm, ServiceName, SERVICE_ALL_ACCESS);
- if(!hService)
- {
- CloseServiceHandle(hScm);
- return 1;
- }
- StartService(hService, 0, NULL);
- CloseServiceHandle(hService);
- CloseServiceHandle(hScm);
- return 0;
- }
-
- if (dwCurrentState == SERVICE_STOPPED && (nAction==2 || (nAction == 0 && MessageBox(0, _T("Uninstall Service?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
- {
- SC_HANDLE hService,hScm;
- hScm=OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
- if(!hScm)
- {
- return 1;
- }
- hService=OpenService(hScm, ServiceName, SERVICE_ALL_ACCESS);
- if(!hService)
- {
- CloseServiceHandle(hScm);
- return 1;
- }
- DeleteService(hService);
- CloseServiceHandle(hService);
- CloseServiceHandle(hScm);
- return 0;
- }
-
- if (dwCurrentState != SERVICE_STOPPED && (nAction==4 || (nAction == 0 && MessageBox(0, _T("Stop Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
- {
- SC_HANDLE hService,hScm;
- hScm=OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
- if(!hScm)
- {
- return 1;
- }
- hService=OpenService(hScm, ServiceName, SERVICE_ALL_ACCESS);
- if(!hService)
- {
- CloseServiceHandle(hScm);
- return 1;
- }
- SERVICE_STATUS status;
- ControlService(hService, SERVICE_CONTROL_STOP, &status);
- CloseServiceHandle(hService);
- CloseServiceHandle(hScm);
- return 0;
- }
-
- if (dwCurrentState == SERVICE_STOPPED)
- return 0;
-
- return 0;
- }
-
- void ServiceMain(DWORD argc, LPTSTR *argv)
- {
- LoadServiceName();
-
- BOOL success;
- nServiceStatusHandle = RegisterServiceCtrlHandler(ServiceName,
- (LPHANDLER_FUNCTION)ServiceCtrlHandler);
- if (!nServiceStatusHandle)
- return;
-
- success = UpdateServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000);
- if (!success)
- return;
-
- killServiceEvent = CreateEvent(0, TRUE, FALSE, 0);
- if (killServiceEvent == NULL)
- return;
-
- success = UpdateServiceStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000);
- if (!success)
- return;
-
- success = StartServiceThread();
- if (!success)
- return;
-
- nServiceCurrentStatus = SERVICE_RUNNING;
- success = UpdateServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
- if (!success)
- return;
-
- WaitForSingleObject(killServiceEvent, INFINITE);
- CloseHandle(killServiceEvent);
- WaitForSingleObject(hServiceThread, INFINITE);
- CloseHandle(hServiceThread);
- UpdateServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
- }
-
- BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
- DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
- DWORD dwWaitHint)
- {
- BOOL success;
- SERVICE_STATUS nServiceStatus;
- nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
- nServiceStatus.dwCurrentState=dwCurrentState;
- if(dwCurrentState==SERVICE_START_PENDING)
- {
- nServiceStatus.dwControlsAccepted=0;
- }
- else
- {
- nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP
- |SERVICE_ACCEPT_SHUTDOWN;
- }
- if(dwServiceSpecificExitCode==0)
- {
- nServiceStatus.dwWin32ExitCode=dwWin32ExitCode;
- }
- else
- {
- nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR;
- }
- nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode;
- nServiceStatus.dwCheckPoint=dwCheckPoint;
- nServiceStatus.dwWaitHint=dwWaitHint;
-
- success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus);
- if(!success)
- {
- KillService();
- return success;
- }
- else
- return success;
- }
-
- BOOL StartServiceThread()
- {
- DWORD id;
- hServiceThread=CreateThread(0,0,
- (LPTHREAD_START_ROUTINE)ServiceExecutionThread,
- 0,0,&id);
- if(hServiceThread==0)
- {
- return false;
- }
- else
- {
- nServiceRunning=true;
- return true;
- }
- }
-
- void KillService()
- {
- if (hMainWnd)
- PostMessage(hMainWnd, WM_CLOSE, 0, 0);
- nServiceRunning = false;
- }
-
-
- static BOOL CALLBACK SendReloadConfigProc(HWND hwnd, LPARAM lParam)
- {
- int* res = (int*)lParam;
-
- TCHAR buffer[100];
-
- if (!GetClassName(hwnd, buffer, 100))
- return TRUE;
-
- if (_tcscmp(buffer, _T("FileZilla Server Helper Window")))
- return TRUE;
-
- if (!GetWindowText(hwnd, buffer, 100))
- return TRUE;
-
- if (_tcscmp(buffer, _T("FileZilla Server Helper Window")))
- return TRUE;
-
- PostMessage(hwnd, WM_FILEZILLA_RELOADCONFIG, 0, 0);
-
- *res = 0;
-
- return TRUE;
- }
-
-
- int SendReloadConfig()
- {
- int res = 1;
- EnumWindows(SendReloadConfigProc, (LPARAM)&res);
-
- return res;
- }
-
-
- void ServiceCtrlHandler(DWORD nControlCode)
- {
- BOOL success;
- switch(nControlCode)
- {
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- nServiceCurrentStatus=SERVICE_STOP_PENDING;
- success=UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
- KillService();
- return;
- case 128:
- SendReloadConfig();
- break;
- default:
- break;
- }
- UpdateServiceStatus(nServiceCurrentStatus,NO_ERROR,0,0,0);
- }
-
- DWORD ServiceExecutionThread(LPDWORD param)
- {
- // initialize Winsock library
- BOOL res=TRUE;
- WSADATA wsaData;
-
- WORD wVersionRequested = MAKEWORD(1, 1);
- int nResult = WSAStartup(wVersionRequested, &wsaData);
- if (nResult != 0)
- res=FALSE;
- else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
- {
- WSACleanup();
- res=FALSE;
- }
-
- if(!res)
- {
- SetEvent(killServiceEvent);
- UpdateServiceStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
- return 0;
- }
-
- CServer *pServer = new CServer;
- VERIFY(pServer->Create());
-
- if (!nServiceRunning)
- PostQuitMessage(0);
-
- MSG msg;
- while (GetMessage(&msg, 0, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- delete pServer;
- WSACleanup();
-
- SetEvent(killServiceEvent);
- return 0;
- }
-
- int SetAdminPort(int nAdminPort)
- {
- if (nAdminPort < 1 || nAdminPort > 65535)
- return 1;
-
- COptions *pOptions = new COptions();
- pOptions->SetOption(OPTION_ADMINPORT, nAdminPort);
- delete pOptions;
-
- pOptions = new COptions();
- if (pOptions->GetOptionVal(OPTION_ADMINPORT) != nAdminPort)
- {
- delete pOptions;
- return 1;
- }
- delete pOptions;
-
- return 0;
- }
-
- int ReloadConfig()
- {
- int res = SendReloadConfig();
-
- SC_HANDLE hService, hScm;
- hScm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
-
- if (hScm)
- {
- hService = OpenService(hScm, ServiceName, SERVICE_USER_DEFINED_CONTROL);
- if (hService)
- {
- SERVICE_STATUS status;
- res |= ControlService(hService, 128, &status) == 0;
- CloseServiceHandle(hService);
- }
- CloseServiceHandle(hScm);
- }
-
- return !res;
- }
-
- int CompatMain(LPCSTR lpCmdLine)
- {
- int nAction = 0;
-
- if (lpCmdLine[0] == '/' || lpCmdLine[0] == '-')
- {
- lpCmdLine++;
- if (!strcmp(lpCmdLine, "start"))
- nAction = 1;
- else if (!strcmp(lpCmdLine, "stop"))
- nAction = 2;
- else if (strlen(lpCmdLine) >= 10 && !strncmp(lpCmdLine, "adminport ", 10))
- nAction = 3;
- else if (!strcmp(lpCmdLine, "install"))
- return 0;
- else if (!strcmp(lpCmdLine, "uninstall"))
- return 0;
- else if (!strcmp(lpCmdLine, "install auto"))
- return 0;
- else if (!strcmp(lpCmdLine, "reload-config"))
- nAction = 4;
- }
-
- if (nAction == 3)
- return SetAdminPort(atoi(lpCmdLine + 10));
- else if (nAction == 4)
- return ReloadConfig();
-
- HWND hWnd = FindWindow(_T("FileZilla Server Helper Window"), _T("FileZilla Server Helper Window"));
- if (nAction == 1 && hWnd)
- return 0;
- else if (nAction==2 && !hWnd)
- return 0;
-
- if (!hWnd && (nAction == 1 || (nAction == 0 && MessageBox(0, _T("Start Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
- {
- // initialize Winsock library
- BOOL res=TRUE;
- WSADATA wsaData;
-
- WORD wVersionRequested = MAKEWORD(1, 1);
- int nResult = WSAStartup(wVersionRequested, &wsaData);
- if (nResult != 0)
- res=FALSE;
- else if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
- {
- WSACleanup();
- res=FALSE;
- }
-
- if(!res)
- {
- return 1;
- }
-
- CServer *pServer = new CServer;
- VERIFY(pServer->Create());
-
- MSG msg;
- while (GetMessage(&msg, 0, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- delete pServer;
- WSACleanup();
- return 0;
- }
- else if (hWnd && (nAction == 2 || (nAction == 0 && MessageBox(0, _T("Stop Server?"), _T("Question"), MB_YESNO|MB_ICONQUESTION)==IDYES)))
- {
- SendMessage(hWnd, WM_CLOSE, 0, 0);
- if (GetLastError())
- return 1;
- else
- return 0;
- }
-
- return 1;
- }